#pragma once

#include "LeGraphicsView.h"

#include <QObject>
#include <QVector>

namespace LeGraphicsView
{

    class OLDGRAPHICSVIEW_EXPORT Ruler : public QObject
    {
        Q_PROPERTY(qreal minimumValueStep READ minimumValueStep WRITE setMinimumValueStep)
        Q_PROPERTY(int minimumTickSpacing READ minimumTickSpacing WRITE setMinimumTickSpacing)
        Q_PROPERTY(int coarseMultiplier READ coarseMultiplier WRITE setCoarseMultiplier)
        Q_PROPERTY(qreal minimumValue READ minimumValue WRITE setMinimumValue)
        Q_PROPERTY(qreal maximumValue READ maximumValue WRITE setMaximumValue)
        Q_PROPERTY(int size READ size WRITE setSize)

        Q_OBJECT
    public:
        explicit Ruler(QObject *parent = 0);

        qreal minimumValueStep() const;
        qreal minimumValue() const;
        qreal maximumValue() const;

        qreal ceilValue(qreal value) const;
        qreal floorValue(qreal value) const;
        qreal roundValue(qreal value) const;

        QVector<qreal> majorValues() const;
        qreal majorValueStep() const;
        QVector<qreal> minorValues() const;
        qreal minorValueStep() const;

        int minimumTickSpacing() const;
        int coarseMultiplier() const;
        int size() const;

        QVector<int> majorTicks() const;
        QVector<int> minorTicks() const;

        int tickPosition(qreal value) const;

    signals:
        void changed() const;

    public slots:
        void setMinimumValueStep(qreal minimumValueStep);
        void setMinimumValue(qreal minimumValue);
        void setMaximumValue(qreal maximumValue);

        void setMinimumTickSpacing(int minimumTickSpacing);
        void setCoarseMultiplier(int coarseMultiplier);
        void setSize(int size);

    private:
        qreal m_minimumValueStep;
        int m_minimumTickSpacing;
        int m_coarseMultiplier;
        qreal m_minimumValue;
        qreal m_maximumValue;
        int m_size;

        void invalidate() const;
        void maybeUpdate() const;
        static qreal normaliseValueStep(qreal step);
        int calculateTickPosition(qreal value) const;
        void updateValueSeries(QVector<qreal> &valueSeries, qreal step) const;
        void updateTickSeries(QVector<int> &tickSeries, const QVector<qreal> &valueSeries) const;

        mutable bool m_needsUpdate;
        mutable qreal m_levelOfDetail;
        mutable qreal m_minorValueStep;
        mutable qreal m_majorValueStep;
        mutable QVector<qreal> m_minorValues;
        mutable QVector<qreal> m_majorValues;
        mutable QVector<int> m_minorTicks;
        mutable QVector<int> m_majorTicks;
    };



}
